﻿#include "MeasureView/MeasureAngle.h"
#include "MeasureView/MeasureDataSet.h"
#include <QtMath>
#include <QDebug>

namespace Qly {

MeasureAngle3P::MeasureAngle3P(MeasureDataSet *parent)
    :MeasureElement(parent)
{
    m_measureType = Angle3P;
    m_results_pix.resize(2);
    m_results_um.resize(2);
    m_keyPoints_pix.resize(3);
    m_keyPoints_um.resize(3);
    m_measureState = DS_IDLE;
    m_textTemplate = parent->m_textTemplate_MeasureAngle3P;
//    m_textTemplate = MeasureAngle3P::s_textTemplate;
}

int MeasureAngle3P::mouseLButtonPress(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_IDLE )
    {
        m_keyPoints_pix[0] = point_pix;
        m_keyPoints_um[0] = point_um;
        m_measureState = DS_STATE1;
        return DS_STATE1;
    }
    if(m_measureState == DS_STATE1)
    {
        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[1] = point_um;
        m_keyPoints_pix[2] = point_pix;
        m_keyPoints_um[2] = point_um;
        if(m_keyPoints_pix[1] == m_keyPoints_pix[0])
        {
            m_measureState = DS_ERROR;
            return DS_ERROR;
        }
        m_measureState = DS_STATE2;
        return DS_STATE2;
    }
    if( m_measureState == DS_STATE2 )
    {
        m_keyPoints_pix[2] = point_pix;
        m_keyPoints_um[2] = point_um;
        compute();
        updateText(true);
        m_measureState = DS_FINISH;

        return DS_FINISH;
    }
    return 0;
}

int MeasureAngle3P::mouseMove(QPointF point_pix, QPointF point_um)
{
    if(m_measureState == DS_STATE2)
    {
        m_keyPoints_pix[2] = point_pix;
        m_keyPoints_um[2] = point_um;
        compute();
        updateText(true);
        return DS_STATE2;
    }
    return 0;
}

//int MeasureAngle3P::setLens(int oldLens, int newLens, int method)
//{
//    if(oldLens == newLens || oldLens == -1) return 0;// 这时不需要更新任何数据
//    if(m_keyPoints_pix.size() != m_keyPoints_um.size()) //这里表示出现了错误，也应该退出
//    {
//        return 0;
//    }
//    LensManager & lens = LensManager::getInstance();
//    if(method == 0)//只更新长度的数值，图元在图像上的位置不变
//    {
//        double new_pixelSize = lens.currentLens().pixelSize_um;
//        for(int  i = 0; i < m_keyPoints_pix.size(); ++i)
//        {
//            m_keyPoints_um[i] = m_keyPoints_pix[i] * new_pixelSize;
//        }
//    }
//    else
//    {
//        LensData & oldData = lens.lensByIndex(oldLens);
//        LensData & newData = lens.currentLens();
//        double dx = (newData.xCompensate_um - oldData.xCompensate_um);
//        double dy = (newData.yCompensate_um - oldData.yCompensate_um);
//        for(int  i = 0; i < m_keyPoints_pix.size(); ++i)
//        {
//            m_keyPoints_pix[i] = (m_keyPoints_um[i] + QPointF(dx, dy)) / newData.pixelSize_um;
//        }
//    }
//    compute();
//    updateText();
//    return 1;
//}

void MeasureAngle3P::compute()
{
    double x1 = m_keyPoints_pix[0].x() - m_keyPoints_pix[2].x();
    double y1 = m_keyPoints_pix[0].y() - m_keyPoints_pix[2].y();

    double x2 = m_keyPoints_pix[1].x() - m_keyPoints_pix[2].x();
    double y2 = m_keyPoints_pix[1].y() - m_keyPoints_pix[2].y();

    double a = hypot(x1, y1);
    double b = hypot(x2, y2);
    double c = hypot(x1-x2, y1-y2);

    double theta = acos((a * a + b * b - c * c) / (2.0 * a * b));
    m_results_pix[0] = theta;
    m_results_um[0] = theta;

    m_results_pix[1] = theta * 180.0 / M_PI;
    m_results_um[1] = m_results_pix[1];
}

void MeasureAngle3P::updateText(bool updatePosition)
{
    //QString text = m_textTemplate;
    QString text = m_textTemplate;
    int precision = m_pParent->m_unitConvert_MeasureAngle3P.precision();
    QString str1 = QString::number(m_results_pix[0], 'f', precision);
    QString str2 = QString::number(m_results_pix[1], 'f', precision);
    text.replace("@angleDeg", str2, Qt::CaseSensitive);
    text.replace("@angle", str1, Qt::CaseSensitive);

    QString str3 = QString::number(m_id);
    text.replace("@id", str3, Qt::CaseSensitive);
    m_textBlock.setText(text);
    //qDebug() << "@angleDeg = " << str2;
    if(updatePosition)
    {
         m_textBlock.moveTo(m_keyPoints_pix[2], m_keyPoints_um[2]);
    }
}

void MeasureAngle3P::paint(QPainter &painter)
{
    if(m_measureState == DS_ERROR || m_measureState == DS_IDLE)
    {
        return;
    }
    painter.save();
    painter.setPen(m_pen);
    drawCross(painter, m_keyPoints_pix[0]);
    if(m_measureState == DS_STATE1)
    {
        painter.restore();
        return;
    }
    drawCross(painter, m_keyPoints_pix[1]);
    painter.drawLine(m_keyPoints_pix[0], m_keyPoints_pix[2]);
    painter.drawLine(m_keyPoints_pix[1], m_keyPoints_pix[2]);
//    if(m_measureState == DS_FINISH)
    {
//        qDebug() << "m_textBlock.draw(painter)";
        m_textBlock.draw(painter);
    }
    if(m_textMoving)
    {
        QPen pen = m_pen;
        pen.setStyle(Qt::DashDotLine);
        painter.setPen(pen);
        QPointF p = m_textBlock.anchorPoint();
        painter.drawLine(p, m_keyPoints_pix[2]);
        painter.setPen(m_pen);
    }
    painter.restore();
}

MeasureAngle4P::MeasureAngle4P(MeasureDataSet *parent)
    :MeasureElement(parent)
{
    m_measureType = Angle4P;
    m_results_pix.resize(3);
    m_results_um.resize(3);
    m_keyPoints_pix.resize(4);
    m_keyPoints_um.resize(4);
    m_measureState = DS_IDLE;

    m_textTemplate = parent->m_textTemplate_MeasureAngle4P;
//    m_textTemplate = MeasureAngle4P::s_textTemplate;
}

//int MeasureAngle4P::setLens(int oldLens, int newLens, int method)
//{
//    if(oldLens == newLens || oldLens == -1) return 0;// 这时不需要更新任何数据
//    if(m_keyPoints_pix.size() != m_keyPoints_um.size()) //这里表示出现了错误，也应该退出
//    {
//        return 0;
//    }
//    LensManager & lens = LensManager::getInstance();
//    if(method == 0)//只更新长度的数值，图元在图像上的位置不变
//    {
//        double new_pixelSize = lens.currentLens().pixelSize_um;
//        for(int  i = 0; i < m_keyPoints_pix.size(); ++i)
//        {
//            m_keyPoints_um[i] = m_keyPoints_pix[i] * new_pixelSize;
//        }
//    }
//    else
//    {
//        LensData & oldData = lens.lensByIndex(oldLens);
//        LensData & newData = lens.currentLens();
//        double dx = (newData.xCompensate_um - oldData.xCompensate_um);
//        double dy = (newData.yCompensate_um - oldData.yCompensate_um);
//        for(int  i = 0; i < m_keyPoints_pix.size(); ++i)
//        {
//            m_keyPoints_pix[i] = (m_keyPoints_um[i] + QPointF(dx, dy)) / newData.pixelSize_um;
//        }
//    }
//    compute();
//    updateText();
//    return 1;
//}

int MeasureAngle4P::mouseLButtonPress(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_IDLE )
    {
        m_keyPoints_pix[0] = point_pix;
        m_keyPoints_um[0] = point_um;

        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[1] = point_um;
        m_measureState = DS_STATE1;
        return DS_STATE1;
    }
    if(m_measureState == DS_STATE1)
    {
        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[1] = point_um;
        if(m_keyPoints_pix[1] == m_keyPoints_pix[0])
        {
            m_measureState = DS_ERROR;
            return m_measureState;
        }
        m_measureState = DS_STATE2;
        return m_measureState;
    }
    if( m_measureState == DS_STATE2 )
    {
        m_keyPoints_pix[2] = point_pix;
        m_keyPoints_um[2] = point_um;
        m_keyPoints_pix[3] = point_pix;
        m_keyPoints_um[3] = point_um;
        m_measureState = DS_STATE3;
        return m_measureState;
    }
    if(m_measureState == DS_STATE3)
    {
        m_keyPoints_pix[3] = point_pix;
        m_keyPoints_um[3] = point_um;
        if(m_keyPoints_pix[2] == m_keyPoints_pix[3])
        {
            m_measureState = DS_ERROR;
            return m_measureState;
        }
        compute();
        updateText(true);

        m_measureState = DS_FINISH;
        return m_measureState;
    }
    return DS_ERROR;
}

int MeasureAngle4P::mouseMove(QPointF point_pix, QPointF point_um)
{
    if(m_measureState == DS_STATE1)
    {
        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[1] = point_um;
        return 3;
    }
    if(m_measureState == DS_STATE3)
    {
        m_keyPoints_pix[3] = point_pix;
        m_keyPoints_um[3] = point_um;
        return 3;
    }
    return 0;
}

void MeasureAngle4P::compute()
{
    double x1 = m_keyPoints_pix[1].x() - m_keyPoints_pix[0].x();
    double y1 = m_keyPoints_pix[1].y() - m_keyPoints_pix[0].y();

    double x2 = m_keyPoints_pix[3].x() - m_keyPoints_pix[2].x();
    double y2 = m_keyPoints_pix[3].y() - m_keyPoints_pix[2].y();

    double a = hypot(x1, y1);
    double b = hypot(x2, y2);
    double c = hypot(x1-x2, y1-y2);

    double theta = acos((a * a + b * b - c * c) / (2.0 * a * b));
    m_results_pix[0] = theta;
    m_results_um[0] = theta;

    m_results_pix[1] = theta * 180.0 / M_PI;
    m_results_um[1] = m_results_pix[1];
}

void MeasureAngle4P::updateText(bool updatePosition)
{
    //QString text = m_textTemplate;
    QString text = m_textTemplate;
    int precision = m_pParent->m_unitConvert_MeasureAngle4P.precision();
    QString str1 = QString::number(m_results_pix[0], 'f', precision);
    QString str2 = QString::number(m_results_pix[1], 'f', precision);
    text.replace("@angleDeg", str2, Qt::CaseSensitive);
    text.replace("@angle", str1, Qt::CaseSensitive);
    QString str3 = QString::number(m_id);
    text.replace("@id", str3, Qt::CaseSensitive);
    m_textBlock.setText(text);
    if(updatePosition)
    {
        QPointF p_pix = (m_keyPoints_pix[0] + m_keyPoints_pix[1] + m_keyPoints_pix[2] + m_keyPoints_pix[3]) / 4.0;
        QPointF p_um = (m_keyPoints_um[0] + m_keyPoints_um[1] + m_keyPoints_um[2] + m_keyPoints_um[3]) / 4.0;
        m_textBlock.moveTo(p_pix, p_um);
    }
}

void MeasureAngle4P::paint(QPainter &painter)
{
    if(m_measureState == DS_ERROR || m_measureState == DS_IDLE)
    {
        return;
    }
    painter.save();
    painter.setPen(m_pen);
    painter.drawLine(m_keyPoints_pix[0], m_keyPoints_pix[1]);
    if(m_measureState == DS_STATE3 || m_measureState == DS_FINISH)
    {
        painter.drawLine(m_keyPoints_pix[2], m_keyPoints_pix[3]);
    }
    m_textBlock.draw(painter);
    if(m_textMoving)
    {
        QPen pen = m_pen;
        pen.setStyle(Qt::DashDotLine);
        painter.setPen(pen);
        QPointF p = m_textBlock.anchorPoint();
        painter.drawLine(p, (m_keyPoints_pix[0] + m_keyPoints_pix[1]) / 2.0);
        painter.drawLine(p, (m_keyPoints_pix[2] + m_keyPoints_pix[3]) / 2.0);
        painter.setPen(m_pen);
    }
    painter.restore();
}

}
